﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TCG.Engine.Effects;
using TCG.Engine.Libraries;
using TCG.Engine.Impacts;

namespace TCG.Engine.Core
{
    public class Card
    {
        public CardInfo Info
        {
            get;
            private set;
        }

        public Card()
        {

        }

        public Card(CardInfo info)
        {
            this.Info = info;
        }

        public void Apply(MoveContext mc)
        {
            List<IImpact> impacts = new List<IImpact>();
            AddSimpleImpacts(impacts);

            AddEffectImpacts(impacts, mc);

            AddCostImpacts(impacts);

            mc.Impacts.AddRange(impacts);

            AssignClasses(mc);
        }

        private void AddEffectImpacts(List<IImpact> impacts, MoveContext mc)
        {
            var effectImpacts = Info.Impacts.Where(ii => ii.Type == ImpactTypeInfo.ApplyEffect);
            foreach (var ei in effectImpacts)
            {
                var effect = Env.Get<IEffectLibrary>().Get(ei.Value) as IDirectEffect;
                if (effect != null)
                {
                    effect.Execute(mc);
                }
                else
                {
                    impacts.Add(ImpactsFactory.ByInfo(ei));
                }
            }
        }

        private void AssignClasses(MoveContext mc)
        {
            mc.Impacts.ForEach(i => i.Classes.AddRange(Info.Classes));
        }

        private void AddCostImpacts(List<IImpact> impacts)
        {
            if (Info.CostGold > 0)
                impacts.Add(ImpactsFactory.CostGold(Info.CostGold, TargerInfo.Self));

            if (Info.CostMana > 0)
                impacts.Add(ImpactsFactory.CostMana(Info.CostMana, TargerInfo.Self));
        }

        private void AddSimpleImpacts(List<IImpact> impacts)
        {
            impacts.AddRange(Info.Impacts.Where(ii => ii.Type != ImpactTypeInfo.ApplyEffect).Select(ii => ImpactsFactory.ByInfo(ii)));
        }
    }
}
